﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Xunit;
using YAPL.Language.SourceParser;
using YAPL.Language.Ast;
using YAPL.Language.SourceParser.XML;

namespace YAPL.Test.YAPL.Language.Parser.XML.NodeParsers {
	public class XmlFunctionDefParserTest : XmlNodeParserTest {

		[Fact]
		public void FunctionDefShouldHaveNameAttribute() {
			var functionDefNode = new XElement(XmlNames.FunctionDefExpression, new XElement(XmlNames.CodeBlockExpression));
			Assert.Throws<ArgumentNullException>(() => _parser.ParseNode(functionDefNode));
		}

		[Fact]
		public void FunctionDefShouldNotHaveEmptyName() {
			var functionDefNode = new XElement(XmlNames.FunctionDefExpression,
				new XAttribute(XmlNames.FunctionNameAttribute, ""),
				new XElement(XmlNames.CodeBlockExpression));

			Assert.Throws<ArgumentException>(() => _parser.ParseNode(functionDefNode));
		}

		[Fact]
		public void FunctionDefShouldHaveCodeBlock() {
			var functionDefNode = new XElement(XmlNames.FunctionDefExpression, new XAttribute(XmlNames.FunctionNameAttribute, "print"));
			Assert.Throws<ArgumentNullException>(() => _parser.ParseNode(functionDefNode));
		}

		[Fact]
		public void EmptyFunctionShouldBeParsedCorrectly() {
			var functionDefNode = new XElement(XmlNames.FunctionDefExpression,
				new XAttribute(XmlNames.FunctionNameAttribute, "print"),
				new XElement(XmlNames.CodeBlockExpression));
			var expr = _parser.ParseNode(functionDefNode);
			Assert.IsType(typeof(FunctionDefExpression),expr);
			var funcDef = (FunctionDefExpression) expr;
			Assert.Equal("print", funcDef.Name);
			Assert.Empty(funcDef.Parameters);
			Assert.Empty(funcDef.FunctionBody.Expressions);
			
		}
	}
}